﻿using System;
using System.Collections.Generic;
using ACompany.OrderProcessing.Model;
using ACompany.OrderProcessing.Services;
using System.Text;
using StructureMap;


public class CreateOrderPresenter
{

    private ICreateOrderView view;
    private IOrderService OrderService;
    private IProductService ProductService;

    private ICustomerService CustomerService;
    public CreateOrderPresenter(ICreateOrderView view)
        : this(view, ObjectFactory.GetInstance<IOrderService>(), ObjectFactory.GetInstance<IProductService>(), ObjectFactory.GetInstance<ICustomerService>())
    {
    }

    public CreateOrderPresenter(ICreateOrderView view, IOrderService orderService, IProductService ProductService, ICustomerService CustomerService)
    {
        this.view = view;
        this.OrderService = orderService;
        this.ProductService = ProductService;
        this.CustomerService = CustomerService;
    }


    public void Display()
    {
        clearInfoAndErrorMessages();

        List<Product> Products = (List<Product>)ProductService.FindAll();
        view.Products = Products;
        view.SelectProductButtonEnabled = (Products.Count > 0);

        List<Customer> Customers = (List<Customer>)CustomerService.FindAll();
        view.Customers = Customers;
        view.SelectCustomerButtonEnabled = (Customers.Count > 0);

        DisplayErrorsWith(Customers, Products);

        if ((Products.Count == 0) & (Customers.Count == 0))
        {
            view.CreateOrderButtonEnabled = false;
        }

    }


    public void PlaceOrder()
    {
        clearInfoAndErrorMessages();

        if (view.Order.GetBrokenRules().Count == 0)
        {
            OrderService.Place(view.Order);
            view.InfoMessage("Order placed successfully");
            view.clearOrder();
        }
        else
        {
            DisplayErrorsIn(view.Order);
        }
    }


    public void AddProductBy(Guid ProductId)
    {
        clearInfoAndErrorMessages();

        if (ProductId != Guid.Empty)
        {
            Product product = ProductService.FindBy(ProductId);

            if (product == null)
            {
                view.ErrorMessage(string.Format("No product found with Id {0}.", ProductId));
            }
            else
            {
                view.Order.Add(product);
                view.OrderItems = view.Order.Items;
            }
        }
        else
        {
            view.ErrorMessage(string.Format("Invalid product Id {0}.", ProductId));
        }
    }


    public void SetCustomerBy(Guid CustomerId)
    {
        clearInfoAndErrorMessages();

        if (CustomerId != Guid.Empty)
        {
            Customer customer = CustomerService.FindBy(CustomerId);

            if (customer == null)
            {
                view.ErrorMessage(string.Format("No Customer found with Id {0}", CustomerId));

            }
            else
            {
                view.Order.Customer = customer;
                view.Order.DespatchAddress = customer.Address;

                view.CustomerName = customer.Name;
                view.Street = customer.Address.Street;
                view.City = customer.Address.City;
                view.County = customer.Address.Country;
                view.PostCode = customer.Address.PostCode;

            }
        }
        else
        {
            view.ErrorMessage(string.Format("Invalid Customer Id {0}", CustomerId));
        }


    }


    private void DisplayErrorsIn(Order Order)
    {
        StringBuilder sbErrorMessage = new StringBuilder();

        sbErrorMessage.Append("There were some problems when trying to place this Order:");
        sbErrorMessage.Append(Environment.NewLine);
        sbErrorMessage.Append(Environment.NewLine);

        foreach (var BrokenRule in Order.GetBrokenRules())
        {
            sbErrorMessage.Append(BrokenRule.Rule);
            sbErrorMessage.Append(Environment.NewLine);
        }

        view.ErrorMessage(sbErrorMessage.ToString());
    }


    private void DisplayErrorsWith(IList<Customer> Customers, IList<Product> Products)
    {
        StringBuilder sbErrorMessage = new StringBuilder();

        if (Customers.Count == 0)
        {
            sbErrorMessage.Append("Please add a customer before creating an order.");
            sbErrorMessage.Append(Environment.NewLine);
        }

        if (Products.Count == 0)
        {
            sbErrorMessage.Append("Please add a product before creating an order.");
            sbErrorMessage.Append(Environment.NewLine);
        }

        view.ErrorMessage(sbErrorMessage.ToString());
    }

    private void clearInfoAndErrorMessages()
    {
        view.ErrorMessage(string.Empty);
        view.InfoMessage(string.Empty);
    }
}